home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
pmode
/
exc_dx02
/
exc_1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-25
|
5KB
|
189 lines
#include <stdio.h>
#include <process.h>
#include <pharlap.h>
#include "exc.h"
#include "uasm.h"
#define MAX_EX 17
#define HOOK_BREAK_POINT 1
/*
* Prototypes
*/
static void HookExcHandler (char i, unsigned int cs);
static char errCodeExc (char i);
static char *errCodeStr (char i,short x);
static void LocalHook (void);
/*
* Public data
*/
FARPTR oldExcHandlers [MAX_EX+1];
/*
* Local data
*/
static void (* excHookUser)(excReg *r);
static char uasmAtExc;
static char privLevel;
/*
* Application interface to exception handler system
* Called once during main start. Add/remove handlers as
* required. Can be invoked multiple times
*/
void InstallExcHandler (void (*userHook)(excReg *r), char debugDump)
{
int i;
unsigned int cseg;
CONFIG_INF cnf;
_dx_config_inf(&cnf,(char*)&cnf); /* get config block */
cseg = cnf.c_cs_sel;
privLevel = cseg & ~3;
/* Save vectors for all exception handlers */
for (i=0; i<MAX_EX; i++)
_dx_excep_get(i,&oldExcHandlers[i]);
#if 1 // normally #if 0 is sufficient
HookExcHandler( 0,cseg); /* divide error exception */
HookExcHandler( 3,cseg); /* break point exception */
HookExcHandler( 4,cseg); /* integer overflow exc */
HookExcHandler( 5,cseg); /* array bound exception */
HookExcHandler( 6,cseg); /* Illegal opcode exception */
HookExcHandler( 7,cseg); /* Coprocessor not present */
HookExcHandler(11,cseg); /* segment not present exc */
HookExcHandler(12,cseg); /* stack fault exception */
#endif
HookExcHandler(13,cseg); /* general protection exc */
HookExcHandler(14,cseg); /* page fault exception */
excHookUser = userHook;
excHookMain = &LocalHook;
uasmAtExc = debugDump;
}
/*
* Should be called by application before exit();
* Although not strictly necessary.
*
*/
void RemoveExcHandler (void)
{
int i;
/* Restore all exception vectors */
for (i=0; i<MAX_EX; i++)
_dx_excep_set(i,oldExcHandlers[i]);
}
/*-----------------------------------------------------------------*/
static char errCodeExc(char i)
{
return (i == 8 || (i>=10 && i<=14));
}
/*-----------------------------------------------------------------*/
static char * errCodeStr(char i,short x)
{
static char buf[23];
if (errCodeExc(i))
{
sprintf(buf,"Error code %Xh. ",x);
return buf;
}
else return "";
}
/*--------------------------------------------------------------*/
void HookExcHandler (char i, unsigned int cs)
{
FARPTR newExcHandler;
#if HOOK_BREAK_POINT == 0
if (i == 3) return;
#endif
if (errCodeExc(i))
{
FP_SET(newExcHandler,&ExcGlue_1,cs);
}
else
{
FP_SET(newExcHandler,&ExcGlue_0,cs);
}
_dx_excep_set(i,newExcHandler);
}
/*-----------------------------------------------------------------*/
static void LocalHook(void)
{
int i;
static excReg *r = &except;
static void *adr;
static char *excName[] = { "Divide Exception", // 0
"Debug Exception",
"NMI !!??", // 2
"Breakpoint",
"Overflow", // 4
"Array Bound Check",
"Invalid Opcode", // 6
"FPU not present",
"Double Fault", // 8
"FPU Segment Overrun",
"Invalid TSS", // 10
"Segment not present",
"Stack Fault", // 12
"General Protection",
"Page Fault", // 14
"FPU Error",
"Alignment Check" }; // 16
RemoveExcHandler();
if (r->number==3 || r->number==4) /* point to INT 3, INTO */
r->EIP -= 1; /* INT 3 = CC, INTO = CE */
printf ("%s (exc %d) occured at (CS:EIP) %04X:%08X\n\n"\
"%sRegisters:\n" \
"EAX %08X EBX %08X ECX %08X EDX %08X\n" \
"ESI %08X EDI %08X EBP %08X ESP %08X\n" \
"DS %04X FS %04X SS %04X\n" \
"ES %04X GS %04X FLG %08X\n",
excName[r->number],r->number,r->CS,r->EIP,
errCodeStr(r->number,r->code),
r->EAX,r->EBX,r->ECX,r->EDX,
r->ESI,r->EDI,r->EBP,r->ESP,
r->DS,r->FS,r->SS,r->ES,r->GS,r->EFL);
if (uasmAtExc)
{
printf("\nInstruction trace:\n");
adr = (void*) r->EIP;
for (i=0; i<8; i++)
{
printf("%02X:%08X %s\n",r->CS,adr,disassemble(adr));
adr = disasm_outAdr;
}
// printf("\nCall Stack:\n"); // whouldn't this be nice :-)
}
if (excHookUser != NULL)
(*excHookUser)(r);
exit((char)r->number);
}